package com.jyxd.web.service.assessment.basic;

import com.google.common.base.CaseFormat;
import com.jyxd.web.dao.basic.CustomContentDao;
import com.jyxd.web.dao.basic.CustomFieldDao;
import com.jyxd.web.dao.basic.InOutAmountDao;
import com.jyxd.web.dao.basic.NurseRecordFormDao;
import com.jyxd.web.data.basic.CustomContent;
import com.jyxd.web.data.basic.CustomField;
import com.jyxd.web.data.basic.InOutAmount;
import com.jyxd.web.data.dto.HttpResult;
import com.jyxd.web.data.dto.InOutAmountAllSumDTO;
import com.jyxd.web.data.dto.InOutAmountStatisticRequestDTO;
import com.jyxd.web.data.dto.InOutAmountStatisticReturnDTO;
import com.jyxd.web.error.JyxdException;
import com.jyxd.web.util.ExcelData;
import com.jyxd.web.util.ExportExcelUtil;
import com.jyxd.web.util.HttpCode;
import com.jyxd.web.util.UUIDUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;

import static com.jyxd.web.config.ConstantConfig.IN_OUT_AMOUNT_ALL_ALLOWANCE_DOSAGE;
import static com.jyxd.web.config.ConstantConfig.IN_OUT_AMOUNT_USE_SURPLUS;
import static com.jyxd.web.util.DateUtil.*;
import static com.jyxd.web.util.ExecuteUtil.*;
import static com.jyxd.web.util.ObjectUtil.castList;
import static com.jyxd.web.util.ObjectUtil.objectStrIsNull;
import static com.jyxd.web.util.StringUtils.isDecimals;

@Service
public class InOUtAmountStatisticsService {

    private static Logger logger = LoggerFactory.getLogger(InOUtAmountStatisticsService.class);
    @Autowired
    private InOutAmountDao inOutAmountDao;

    @Autowired
    private CustomFieldDao customFieldDao;

    @Autowired
    private CustomContentDao customContentDao;

    @Autowired
    private NurseRecordFormDao nurseRecordFormDao;

    /**
     * 时间段内出入量统计
     *
     * @return
     */
    public String timeQuantumStatistics(Map<String, Object> map) throws Exception {
        errorIfEmpty(map, "查询参数不存在");
        errorIfEmpty(map.get("patientId"), "查询患者id为空");
        errorIfEmpty(map.get("startTime"), "查询开始时间为空");
        errorIfEmpty(map.get("endTime"), "查询结束时间为空");
        String flag = map.get("flag").toString();
        JSONObject inOutAmountJson = getInOutAmountList(map);
        Object data = inOutAmountJson.get("data");
        List<Map> inOutAmountMapList = castList(data, Map.class);
        Map<String, Double> calculateAccumulationMap = new HashMap<>();
        //初始化统计数据
        accumulationInitialize(calculateAccumulationMap);
        if (CollectionUtils.isEmpty(inOutAmountMapList)) {
            inOutAmountJson.put("data", "暂无数据");
            return inOutAmountJson.toString();
        }
        for (int i = 0; i < inOutAmountMapList.size(); i++) {
            Map inOutAmountMap = inOutAmountMapList.get(i);
            if (Objects.isNull(inOutAmountMap.get("flag"))) {
                //提取原数据中的数值
                Map<String, Double> stringIntegerMap = extractNum(inOutAmountMap, findCustomContent(inOutAmountMap), inOutAmountMapList);
                //计算累加值
                calculateAccumulation(calculateAccumulationMap, stringIntegerMap);
            } else if (Objects.equals(flag, inOutAmountMap.get("flag"))) {
                inOutAmountMapList.remove(i);
                i -= 1;
            }
        }
        Date startTime = yyyyMMddHHmmssSdfToDate(String.valueOf(map.get("startTime")));
        Date endTime = yyyyMMddHHmmssSdfToDate(String.valueOf(map.get("endTime")));
        inOutAmountMapList.add(mapDataTransition(calculateAccumulationMap, inOutAmountMapList.get(0), null, null, null, endTime, startTime));
        if (flag.equals("小结")) {
            String order_name = inOutAmountMapList.get(inOutAmountMapList.size() - 1).get("order_name").toString();
            String replace = order_name.replace("总结", "小结");
            inOutAmountMapList.get(inOutAmountMapList.size() - 1).put("order_name", replace);
        }
        inOutAmountMapList.get(inOutAmountMapList.size() - 1).put("flag", flag);
        saveStatisticsData(inOutAmountMapList.get(inOutAmountMapList.size() - 1));
        if (inOutAmountMapList.size() > 0) {
            if (inOutAmountMapList.get(0).get("order_name").toString().contains("小结") || inOutAmountMapList.get(0).get("order_name").toString().contains("总结")) {
                inOutAmountMapList.remove(0);
            }
        }

        inOutAmountJson.put("data", inOutAmountMapList);
        return inOutAmountJson.toString();
    }

    /**
     * 每次统计完后保存统计数据到数据库
     */
    public void saveStatisticsData(Map<String, Object> inOutAmountMap) throws Exception {
        if (CollectionUtils.isEmpty(inOutAmountMap)) {
            return;
        }
        Map<String, Object> map = new HashMap<>();
        map.put("patientId", inOutAmountMap.get("patient_id"));
        map.put("dataTime", inOutAmountMap.get("data_date") + " " + inOutAmountMap.get("data_time"));
        map.put("flag", inOutAmountMap.get("flag"));
        InOutAmount inOutAmount = inOutAmountDao.queryDataByDataTimeAndFlag(map);
        if (Objects.nonNull(inOutAmount)) {
            inOutAmount = setStatisticsValue(inOutAmount, inOutAmountMap);
            inOutAmountDao.update(inOutAmount);
        } else {
            inOutAmount = new InOutAmount();
            inOutAmount.setId(UUIDUtil.getUUID());
            inOutAmount.setCreateTime(new Date());
            inOutAmount = setStatisticsValue(inOutAmount, inOutAmountMap);
            inOutAmountDao.insert(inOutAmount);
        }
        //将自定义数据新增到数据库
        map = new HashMap<>();
        map.put("associatedTable", "table_in_out_amount");
        map.put("associatedTableId", inOutAmount.getId());
        List<CustomContent> customContentList = customContentDao.getByAssociatedTableId(map);
        CustomContent customContent = null;
        if (CollectionUtils.isEmpty(customContentList)) {
            customContent = new CustomContent();
            customContent.setId(UUIDUtil.getUUID());
            customContent.setPatientId(inOutAmount.getPatientId());
            customContent.setAssociatedTable("table_in_out_amount");
            customContent.setAssociatedTableId(inOutAmount.getId());
            customContent.setCreateTime(new Date());
            customContent.setDataTime(inOutAmount.getDataTime());
            customContent.setFlag(inOutAmount.getFlag());
            customContent = setStatisticeCustoContent(customContent, inOutAmountMap);
            customContentDao.insert(customContent);
        } else {
            customContent = customContentList.get(0);
            customContent.setCreateTime(new Date());
            customContent = setStatisticeCustoContent(customContent, inOutAmountMap);
            customContentDao.update(customContent);
        }
    }

    private CustomContent setStatisticeCustoContent(CustomContent customContent, Map<String, Object> inOutAmountMap) throws Exception {
        Field[] fieldCustomContentList = customContent.getClass().getDeclaredFields();
        for (int i = 0, len = fieldCustomContentList.length; i < len; i++) {
            //这个是，有的字段是用private修饰的 将他设置为可读
            fieldCustomContentList[i].setAccessible(true);
            //获取字段名
            String fieldName = fieldCustomContentList[i].getName();
            String humpToUnderline = humpToUnderline(fieldName);
            if (StringUtils.contains(humpToUnderline, "content")) {
                fieldCustomContentList[i].set(customContent, String.valueOf(inOutAmountMap.get(humpToUnderline)));
            }
        }
        return customContent;
    }

    private InOutAmount setStatisticsValue(InOutAmount inOutAmount, Map<String, Object> inOutAmountMap) throws Exception {
        Field[] fields = inOutAmount.getClass().getDeclaredFields();
        for (int i = 0, len = fields.length; i < len; i++) {
            //这个是，有的字段是用private修饰的 将他设置为可读
            fields[i].setAccessible(true);
            //获取字段名
            String fieldName = fields[i].getName();
            String humpToUnderline = humpToUnderline(fieldName);

            if (!humpToUnderline.equals("serial_version_u_i_d")
                    && !humpToUnderline.equals("id")
                    && !humpToUnderline.equals("create_time")) {
                if (humpToUnderline.equals("data_time")) {
                    fields[i].set(inOutAmount, yyyyMMddHHmmssSdfToDate(String.valueOf(inOutAmountMap.get("data_date")) + " " + inOutAmountMap.get("data_time")));
                } else if ((humpToUnderline.equals("start_time") && StringUtils.isNotEmpty((String) inOutAmountMap.get(humpToUnderline))) || (humpToUnderline.equals("end_time")) && StringUtils.isNotEmpty((String) inOutAmountMap.get(humpToUnderline))) {
                    if (((String) inOutAmountMap.get(humpToUnderline)).equals("-")) {
                        fields[i].set(inOutAmount, null);
                    } else {
                        fields[i].set(inOutAmount, yyyyMMddHHmmssSdfToDate(String.valueOf(inOutAmountMap.get(humpToUnderline))));
                    }
                } else if ((humpToUnderline.equals("end_time")) && StringUtils.isEmpty((String) inOutAmountMap.get(humpToUnderline))) {
                    fields[i].set(inOutAmount, null);
                } else if ((humpToUnderline.equals("start_time")) && StringUtils.isEmpty((String) inOutAmountMap.get(humpToUnderline))) {
                    fields[i].set(inOutAmount, null);
                } else if (humpToUnderline.equals("status") || humpToUnderline.equals("type")) {
                    fields[i].set(inOutAmount, (int) inOutAmountMap.get(humpToUnderline));
                } else {
                    fields[i].set(inOutAmount, String.valueOf(inOutAmountMap.get(humpToUnderline)));
                }
            }
        }
        return inOutAmount;
    }

    /**
     * 将驼峰命名改为下划线
     *
     * @param name
     * @return
     */
    private String humpToUnderline(String name) {
        return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, name);
    }

    /**
     * 出入量统计
     *
     * @return
     */
    public String statistics(Map<String, Object> map) throws ParseException {
        isMapNull(map);
        //统计时刻
        String countingTime = String.valueOf(map.get("countingTime"));
        //小结间隔
        Long countingHours = Long.valueOf(String.valueOf(map.get("countingHours")));
        Long summaryHours = 0L;
        //是否需要大结，null不需要，false 为还未大结，true为已经大结
        if (!objectStrIsNull(map.get("summaryHours"))) {
            summaryHours = Long.valueOf(String.valueOf(map.get("summaryHours")));
        }
        //查询数据结束时间
        Date startTime = yyyyMMddHHmmssSdfToDate(String.valueOf(map.get("startTime")));
        Date endDataTime = getLaterHoursDate(startTime, Long.valueOf(String.valueOf(map.get("hours"))));
        map.put("endTime", yyyyMMddHHmmssSdfToString(endDataTime));
        JSONObject inOutAmountJson = getInOutAmountList(map);
        Object data = inOutAmountJson.get("data");
        List<Map> inOutAmountMapList = castList(data, Map.class);
        List<Map> newOutAmountMapList = new ArrayList<>();
        if (CollectionUtils.isEmpty(inOutAmountMapList)) {
            return inOutAmountJson.toString();
        }
        //第一条数据
        Map oneData = inOutAmountMapList.get(0);
        //第一条数据的时间
        Date oneStartTime = yyyyMMddHHmmssSdfToDate(oneData.get("data_date") + " " + oneData.get("data_time") + ":00");
        //计算出第一次统计结束的时间
        Date oneEndTime = calculateOneStatisticsEndTime(String.valueOf(oneData.get("data_date")), String.valueOf(oneData.get("data_time")), countingTime);
        int oneStatisticsCount = 0;
        List<Map> statisticsList = new ArrayList<>();
        //计算出第一段内容的小结时间点
        Date oneCountingTime = getLaterHoursDate(hhmmSdfToDate(countingTime), countingHours);
        //计算出第一段内容的整个小结时间点
        String oneCountingDateStr = oneData.get("data_date") + " " + hhmmssSdfToString(oneCountingTime);
        //转为时间格式
        Date oneCountingDate = yyyyMMddHHmmssSdfToDate(oneCountingDateStr);
        int oneCountingNum = 0;
        for (int i = 0; i < inOutAmountMapList.size(); i++) {
            Map inOutAmountMap = inOutAmountMapList.get(i);
            if (objectStrIsNull(inOutAmountMap.get("data_date"))) {
                continue;
            }
            if (objectStrIsNull(inOutAmountMap.get("data_time"))) {
                continue;
            }
            Date date = yyyyMMddHHmmssSdfToDate(inOutAmountMap.get("data_date") + " " + inOutAmountMap.get("data_time") + ":00");
            if (date.getTime() > oneCountingDate.getTime() && oneStartTime.getTime() < oneCountingDate.getTime() && oneCountingNum == 0) {
                newOutAmountMapList.add(mapDataTransition(addStatisticsDate(statisticsList), inOutAmountMap, countingHours, null, null, oneCountingDate, oneStartTime));
                oneCountingNum += 1;
            }
            if (oneStartTime.getTime() <= date.getTime() && date.getTime() <= oneEndTime.getTime()) {
                statisticsList.add(inOutAmountMap);
                newOutAmountMapList.add(inOutAmountMap);
            } else {
                oneStatisticsCount = i;
                break;
            }
        }
        //插入第一次节点总结
        newOutAmountMapList.add(mapDataTransition(addStatisticsDate(statisticsList), inOutAmountMapList.get(oneStatisticsCount), null, null, countingTime, oneEndTime, oneStartTime));
        if (oneStatisticsCount > 0) {
            //小结计算集合
            Map<String, Double> calculateCountingHoursAccumulationMap = new HashMap<>();
            //初始化小结数据
            accumulationInitialize(calculateCountingHoursAccumulationMap);
            //总结计算集合
            Map<String, Double> calculateSummaryHoursAccumulationMap = new HashMap<>();
            //初始化总结数据
            accumulationInitialize(calculateSummaryHoursAccumulationMap);
            //获取当前数据
            Date inOutAmountMapDateTime = yyyyMMddHHmmssSdfToDate(inOutAmountMapList.get(oneStatisticsCount).get("data_date") + " " + inOutAmountMapList.get(oneStatisticsCount).get("data_time") + ":00");
            //获取计算下一个小结时间节点
            Date countingHoursEndTime = getLaterHoursDate(oneEndTime, calculateStartTime(oneEndTime, inOutAmountMapDateTime, countingHours));
            //获取计算下一个总结时间节点
            Date summaryHoursEndTime = null;
            if (Objects.nonNull(summaryHours) && summaryHours != 0) {
                summaryHoursEndTime = getLaterHoursDate(oneEndTime, calculateStartTime(oneEndTime, inOutAmountMapDateTime, summaryHours));
            }
            for (int i = oneStatisticsCount; i < inOutAmountMapList.size() && oneStatisticsCount != 0; i++) {
                Map inOutAmountMap = inOutAmountMapList.get(i);
                Map inOutAmountNextMap = inOutAmountMap;
                if (i < inOutAmountMapList.size() - 1) {
                    inOutAmountNextMap = inOutAmountMapList.get(i + 1);
                }
                logger.info("计算小结时间：{" + yyyyMMddHHmmssSdfToString(countingHoursEndTime) + "},计算总结时间{" + yyyyMMddHHmmssSdfToString(summaryHoursEndTime) + "}");
                //提取原数据中的数值
                Map<String, Double> stringIntegerMap = extractNum(inOutAmountMap, findCustomContent(inOutAmountMap), inOutAmountMapList);
                //计算小结累加值
                calculateAccumulation(calculateCountingHoursAccumulationMap, stringIntegerMap);
                //如果存在总结时计算总结累加值
                if (Objects.nonNull(summaryHoursEndTime)) {
                    calculateAccumulation(calculateSummaryHoursAccumulationMap, stringIntegerMap);
                }
                //获取下一条数据的时间
                Date inOutAmountNextMapDateTime = yyyyMMddHHmmssSdfToDate(inOutAmountNextMap.get("data_date") + " " + inOutAmountNextMap.get("data_time") + ":00");
                //将原数据放入新集合
                newOutAmountMapList.add(inOutAmountMap);
                //判断如果下次时间大于节点结束时间则进入小结总结
                if (inOutAmountNextMapDateTime.getTime() > countingHoursEndTime.getTime() && i != inOutAmountMapList.size() - 1) {
                    //转换统计数值为前端数据
                    Map mapDataTransition = mapDataTransition(calculateCountingHoursAccumulationMap, inOutAmountMap, countingHours, null, countingTime, countingHoursEndTime, oneStartTime);
                    //小结数据放入新集合中
                    newOutAmountMapList.add(mapDataTransition);
                    //小结结束，初始化计算数据
                    accumulationInitialize(calculateCountingHoursAccumulationMap);
                    //计算下一次时间
                    countingHoursEndTime = getLaterHoursDate(countingHoursEndTime, calculateStartTime(countingHoursEndTime, inOutAmountNextMapDateTime, countingHours));
                } else if (i == inOutAmountMapList.size() - 1) {
                    //最后一条数据直接进行小结结束，不在判断是否是小于下一条数据
                    //转换统计数值为前端数据
                    Map mapDataTransition;
                    mapDataTransition = mapDataTransition(calculateCountingHoursAccumulationMap, inOutAmountMap, countingHours, null, countingTime, countingHoursEndTime, oneStartTime);
                    //小结数据放入新集合中
                    newOutAmountMapList.add(mapDataTransition);
                    if (Objects.nonNull(summaryHoursEndTime)) {
                        //如果需要总结时，转换总结数据为前端所需数据，将总结数据放入集合
                        mapDataTransition = mapDataTransition(calculateSummaryHoursAccumulationMap, inOutAmountMap, null, summaryHours, countingTime, summaryHoursEndTime, oneStartTime);
                        newOutAmountMapList.add(mapDataTransition);
                    }
                    break;
                }
                //如果总结时间不存在，则直接返回
                if (Objects.isNull(summaryHoursEndTime)) {
                    continue;
                }
                if (inOutAmountNextMapDateTime.getTime() > summaryHoursEndTime.getTime()) {
                    //转换统计数值为前端数据
                    Map mapDataTransition = mapDataTransition(calculateSummaryHoursAccumulationMap, inOutAmountMap, null, summaryHours, countingTime, summaryHoursEndTime, oneStartTime);
                    //总结数据放入新集合中
                    newOutAmountMapList.add(mapDataTransition);
                    //总结结束，初始化计算数据
                    accumulationInitialize(calculateSummaryHoursAccumulationMap);
                    //计算下一次总结时间
                    summaryHoursEndTime = getLaterHoursDate(summaryHoursEndTime, calculateStartTime(summaryHoursEndTime, inOutAmountNextMapDateTime, summaryHours));
                }
            }
        }


        inOutAmountJson.put("data", JSONArray.fromObject(newOutAmountMapList));
        return inOutAmountJson.toString();
    }

    /**
     * 计算出中间相差几个时段间隔
     *
     * @param startTime
     * @param nextTime
     * @param countingHoursOrSummaryHours
     * @return
     */
    private long calculateStartTime(Date startTime, Date nextTime, long countingHoursOrSummaryHours) {
        Long difference = nextTime.getTime() - startTime.getTime();
        difference = difference / 1000 / (60 * 60);
        if (difference % countingHoursOrSummaryHours > 0) {
            Long divisor = (difference / countingHoursOrSummaryHours) + 1;
            return divisor * countingHoursOrSummaryHours;
        }
        Long divisor = difference / countingHoursOrSummaryHours;
        return divisor * countingHoursOrSummaryHours;
    }


    /**
     * 计算第一次统计结束时间
     *
     * @return
     */
    private Date calculateOneStatisticsEndTime(String oneDateDay, String oneDateTime, String countingTime) throws ParseException {
        Date oneDateTimeDate = hhmmSdfToDate(oneDateTime);
        Date countingTimeDate = hhmmSdfToDate(countingTime);
        if (oneDateTimeDate.getTime() > countingTimeDate.getTime()) {
            Date date = yyyyMMddHHmmssSdfToDate(oneDateDay + " " + countingTime);
            return getLaterHoursDate(date, 24L);
        }
        return yyyyMMddHHmmssSdfToDate(oneDateDay + " " + countingTime);
    }

    /**
     * 转换为前端数据
     *
     * @return
     */
    private Map<String, Object> mapDataTransition(Map<String, Double> statisticsMap,
                                                  Map<String, Object> mapDate, Long countingHours,
                                                  Long summaryHours, String countingTime, Date dataDate,
                                                  Date oneDateTime) {
        Map<String, Object> map = new HashMap<>();
        for (Map.Entry<String, Object> entry : mapDate.entrySet()) {
            if (StringUtils.equals("dosage", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("dosage") == 0.0 ? "-" : preciseDouble(statisticsMap.get("dosage")));
                continue;
            }
            if (StringUtils.equals("allowance_dosage", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("allowanceDosage") == 0.0 ? "-" : preciseDouble(statisticsMap.get("allowanceDosage")));
                continue;
            }
            if (StringUtils.equals("surplus", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("surplus") == 0.0 ? "-" : preciseDouble(statisticsMap.get("surplus")));
                continue;
            }
            if (StringUtils.equals("piss", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("piss") == 0.0 ? "-" : statisticsMap.get("piss"));
                continue;
            }
            if (StringUtils.equals("faces", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("faces") == 0.0 ? "-" : statisticsMap.get("faces"));
                continue;
            }
            if (StringUtils.equals("drainage", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("drainage") == 0.0 ? "-" : statisticsMap.get("drainage"));
                continue;
            }
            if (StringUtils.equals("balance", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("balance") == 0.0 ? 0.0 : preciseDouble(statisticsMap.get("balance")));
                continue;
            }
            if (StringUtils.equals("content_one", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("contentOne") == 0.0 ? "-" : statisticsMap.get("contentOne"));
                continue;
            }
            if (StringUtils.equals("content_two", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("contentTwo") == 0.0 ? "-" : statisticsMap.get("contentTwo"));
                continue;
            }
            if (StringUtils.equals("content_three", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("contentThree") == 0.0 ? "-" : statisticsMap.get("contentThree"));
                continue;
            }
            if (StringUtils.equals("content_four", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("contentFour") == 0.0 ? "-" : statisticsMap.get("contentFour"));
                continue;
            }
            if (StringUtils.equals("content_five", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("contentFive") == 0.0 ? "-" : statisticsMap.get("contentFive"));
                continue;
            }
            if (StringUtils.equals("content_six", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("contentSix") == 0.0 ? "-" : statisticsMap.get("contentSix"));
                continue;
            }
            if (StringUtils.equals("content_seven", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("contentSeven") == 0.0 ? "-" : statisticsMap.get("contentSeven"));
                continue;
            }
            if (StringUtils.equals("content_eight", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("contentEight") == 0.0 ? "-" : statisticsMap.get("contentEight"));
                continue;
            }
            if (StringUtils.equals("content_nine", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("contentNine") == 0.0 ? "-" : statisticsMap.get("contentNine"));
                continue;
            }
            if (StringUtils.equals("content_ten", entry.getKey())) {
                map.put(entry.getKey(), statisticsMap.get("contentTen") == 0.0 ? "-" : statisticsMap.get("contentTen"));
                continue;
            }
            if (StringUtils.equals("signature", entry.getKey())) {
                map.put(entry.getKey(), "");
                continue;
            }
            if (StringUtils.equals("check_signature", entry.getKey())) {
                map.put(entry.getKey(), "");
                continue;
            }
            if (StringUtils.equals("data_date", entry.getKey())) {
                map.put(entry.getKey(), yyyyMMddSdfToString(dataDate));
                continue;
            }
            if (StringUtils.equals("illness_records", entry.getKey())) {
                map.put(entry.getKey(), "");
                continue;
            }
            if (StringUtils.equals("start_time", entry.getKey())) {
                map.put(entry.getKey(), "-");
                continue;
            }
            if (StringUtils.equals("end_time", entry.getKey())) {
                map.put(entry.getKey(), "-");
                continue;
            }
            if (StringUtils.equals("rate", entry.getKey())) {
                map.put(entry.getKey(), "-");
                continue;
            }
            if ((Objects.isNull(countingHours) && Objects.isNull(summaryHours) && Objects.isNull(countingTime))
                    || Objects.nonNull(summaryHours)) {
                if (StringUtils.equals("data_time", entry.getKey())) {
                    //map.put(entry.getKey(), hhmmssSdfToString(getLaterHoursDate(hhmmSdfToDate(countingTime), summaryHours)));
                    map.put(entry.getKey(), hhmmssSdfToString(dataDate));
                    continue;
                }
                if (StringUtils.equals("order_name", entry.getKey())) {
                    map.put("order_name", getSumTime(oneDateTime, dataDate) + "总结");
                    map.put("flag", "总结");
                    continue;
                }
            } else if (Objects.isNull(countingHours) && Objects.isNull(summaryHours)) {
                if (StringUtils.equals("data_time", entry.getKey())) {
                    map.put(entry.getKey(), countingTime);
                    continue;
                }
                if (StringUtils.equals("order_name", entry.getKey())) {
                    map.put("order_name", getSumTime(oneDateTime, dataDate) + "总结");
                    map.put("flag", "总结");
                    continue;
                }
            } /*else if (Objects.nonNull(summaryHours)) {
                if (StringUtils.equals("data_time", entry.getKey())) {
                    //map.put(entry.getKey(), hhmmssSdfToString(getLaterHoursDate(hhmmSdfToDate(countingTime), summaryHours)));
                    map.put(entry.getKey(), hhmmssSdfToString(dataDate));
                    continue;
                }
                if (StringUtils.equals("order_name", entry.getKey())) {
                    map.put("order_name", getSumTime(oneDateTime, dataDate) + "总结");
                    continue;
                }
            }*/ else if (Objects.nonNull(countingHours)) {
                if (StringUtils.equals("data_time", entry.getKey())) {
                    map.put(entry.getKey(), hhmmssSdfToString(dataDate));
                    continue;
                }
                if (StringUtils.equals("order_name", entry.getKey())) {
                    map.put("order_name", getSumTime(oneDateTime, dataDate) + "小结");
                    map.put("flag", "小结");
                    continue;
                }
            }
            map.put(entry.getKey(), entry.getValue());
        }
        return countToTalOutNum(map);
    }

    /**
     * 计算统计时刻内的总出量
     *
     * @param map
     * @return
     */
    private Map<String, Object> countToTalOutNum(Map<String, Object> map) {
        if (CollectionUtils.isEmpty(map)) {
            return map;
        }
        if (Objects.isNull(map.get("dosage")) || Objects.equals(map.get("dosage"), "-")) {
            return map;
        }
        if (Objects.isNull(map.get("balance")) || Objects.equals(map.get("balance"), "-")) {
            return map;
        }
        double dosage = (double) map.get("dosage");
        if (Objects.nonNull(map.get("allowance_dosage")) && !Objects.equals(map.get("allowance_dosage"), "-")) {
            double allowanceDosage = (double) map.get("allowance_dosage");
            //dosage = dosage - allowanceDosage;
            map.put("dosage", preciseDouble(dosage));
        }
        double balance = (double) map.get("balance");
        map.put("total_out_num", preciseDouble(dosage - balance));
        return map;
    }


    /**
     * 计算第一次节点总结
     *
     * @param statisticsList
     * @throws ParseException
     */
    private Map<String, Double> addStatisticsDate(List<Map> statisticsList) throws ParseException {
        Map<String, Double> calculateAccumulationMap = new HashMap<>();
        calculateAccumulationMap = accumulationInitialize(calculateAccumulationMap);
        for (Map statistics : statisticsList) {
            Map<String, Double> stringIntegerMap = extractNum(statistics, findCustomContent(statistics), statisticsList);
            calculateAccumulation(calculateAccumulationMap, stringIntegerMap);
        }
        return calculateAccumulationMap;
    }

    /**
     * 查询自定义数据
     *
     * @param statisticsMap
     * @return
     */
    private CustomContent findCustomContent(Map<String, Object> statisticsMap) {
        Map<String, Object> map = new HashMap<>();
        map.put("patientId", statisticsMap.get("patient_id"));
        map.put("associatedTable", "table_in_out_amount");
        map.put("dataTime", statisticsMap.get("data_date") + " " + statisticsMap.get("data_time") + ":00");
        if (statisticsMap.containsKey("id")) {
            map.put("associatedTableId", statisticsMap.get("id"));
        }
        List<CustomContent> list = customContentDao.getCustomContentByTime(map);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        return list.get(0);
    }

    /**
     * 初始化原始参数
     *
     * @param calculateAccumulationMap
     * @return
     */
    private Map accumulationInitialize(Map<String, Double> calculateAccumulationMap) {
        calculateAccumulationMap.put("dosage", 0.0);
        calculateAccumulationMap.put("allowanceDosage", 0.0);
        calculateAccumulationMap.put("surplus", 0.0);
        calculateAccumulationMap.put("piss", 0.0);
        calculateAccumulationMap.put("faces", 0.0);
        calculateAccumulationMap.put("drainage", 0.0);
        calculateAccumulationMap.put("balance", 0.0);
        calculateAccumulationMap.put("contentOne", 0.0);
        calculateAccumulationMap.put("contentTwo", 0.0);
        calculateAccumulationMap.put("contentThree", 0.0);
        calculateAccumulationMap.put("contentFour", 0.0);
        calculateAccumulationMap.put("contentFive", 0.0);
        calculateAccumulationMap.put("contentSix", 0.0);
        calculateAccumulationMap.put("contentSeven", 0.0);
        calculateAccumulationMap.put("contentEight", 0.0);
        calculateAccumulationMap.put("contentNine", 0.0);
        calculateAccumulationMap.put("contentTen", 0.0);
        return calculateAccumulationMap;
    }

    /**
     * 计算累加
     *
     * @return
     */
    private Map<String, Double> calculateAccumulation
    (Map<String, Double> calculateAccumulationMap, Map<String, Double> stringIntegerMap) {
        Double dosage = stringIntegerMap.get("dosageCount");
        /**
         * 判断如果备用量不为空，实用量dosage=备用量allowance_dosage-余量surplus
         * 如果为空，实用量=实用量-余量
         */
        /*if (stringIntegerMap.get("allowanceDosageCount") != null && !"".equals(stringIntegerMap.get("allowanceDosageCount")) && stringIntegerMap.get("allowanceDosageCount") > 0) {
            calculateAccumulationMap.put("dosage", calculateAccumulationMap.get("dosage") + stringIntegerMap.get("allowanceDosageCount") - stringIntegerMap.get("surplusCountOld"));
        } else {
            calculateAccumulationMap.put("dosage", calculateAccumulationMap.get("dosage") + stringIntegerMap.get("dosageCount") - stringIntegerMap.get("surplusCountOld"));
        }*/
        calculateAccumulationMap.put("dosage", dosage + calculateAccumulationMap.get("dosage"));
        Double allowanceDosageCount = stringIntegerMap.get("allowanceDosageCount");
        calculateAccumulationMap.put("allowanceDosage", allowanceDosageCount + calculateAccumulationMap.get("allowanceDosage"));

        Double surplusCount = stringIntegerMap.get("surplusCount");
        calculateAccumulationMap.put("surplus", surplusCount + calculateAccumulationMap.get("surplus"));

        Double piss = stringIntegerMap.get("pissCount");
        calculateAccumulationMap.put("piss", piss + calculateAccumulationMap.get("piss"));
        Double faces = stringIntegerMap.get("facesCount");
        calculateAccumulationMap.put("faces", faces + calculateAccumulationMap.get("faces"));
        Double drainage = stringIntegerMap.get("drainageCount");
        calculateAccumulationMap.put("drainage", drainage + calculateAccumulationMap.get("drainage"));
        Double balance = stringIntegerMap.get("balanceCount");
        calculateAccumulationMap.put("balance", balance + calculateAccumulationMap.get("balance"));
        Double contentOne = getCustomData(stringIntegerMap.get("contentOne"));
        calculateAccumulationMap.put("contentOne", contentOne + calculateAccumulationMap.get("contentOne"));

        Double contentTwo = getCustomData(stringIntegerMap.get("contentTwo"));
        calculateAccumulationMap.put("contentTwo", contentTwo + calculateAccumulationMap.get("contentTwo"));

        Double contentThree = getCustomData(stringIntegerMap.get("contentThree"));
        calculateAccumulationMap.put("contentThree", contentThree + calculateAccumulationMap.get("contentThree"));

        Double contentFour = getCustomData(stringIntegerMap.get("contentFour"));
        calculateAccumulationMap.put("contentFour", contentFour + calculateAccumulationMap.get("contentFour"));

        Double contentFive = getCustomData(stringIntegerMap.get("contentFive"));
        calculateAccumulationMap.put("contentFive", contentFive + calculateAccumulationMap.get("contentFive"));

        Double contentSix = getCustomData(stringIntegerMap.get("contentSix"));
        calculateAccumulationMap.put("contentSix", contentSix + calculateAccumulationMap.get("contentSix"));

        Double contentSeven = getCustomData(stringIntegerMap.get("contentSeven"));
        calculateAccumulationMap.put("contentSeven", contentSeven + calculateAccumulationMap.get("contentSeven"));

        Double contentEight = getCustomData(stringIntegerMap.get("contentEight"));
        calculateAccumulationMap.put("contentEight", contentEight + calculateAccumulationMap.get("contentEight"));

        Double contentNine = getCustomData(stringIntegerMap.get("contentNine"));
        calculateAccumulationMap.put("contentNine", contentNine + calculateAccumulationMap.get("contentNine"));

        Double contentTen = getCustomData(stringIntegerMap.get("contentTen"));
        calculateAccumulationMap.put("contentTen", contentTen + calculateAccumulationMap.get("contentTen"));
        return calculateAccumulationMap;
    }

    /**
     * 获取自定义数据
     *
     * @return
     */
    private Double getCustomData(Double customDate) {
        if (Objects.isNull(customDate)) {
            return 0.0;
        }
        return customDate;
    }


    /**
     * 获取余量数据
     *
     * @param statistics
     * @return
     */
    private Double getSurplusCount(Map statistics, List<Map> inOutAmountMapList) {
        errorIfEmpty(statistics, "出入量数据为空");
        String useSign = (String) statistics.get("useSign");
        String parentId = (String) statistics.get("parentId");
        if (isEmpty(parentId) && isExistThisParentId(inOutAmountMapList, (String) statistics.get("id"))) {
            return 0.0;
        }
        if (isNotEmpty(parentId)) {
            if (!isExistThisDataList(inOutAmountMapList, parentId) && StringUtils.contains(useSign, IN_OUT_AMOUNT_USE_SURPLUS))
                return 0.0;
            if (isExistThisParentId(inOutAmountMapList, (String) statistics.get("id")))
                return 0.0;
        }
        return objectToInt(statistics.get("surplus"));
    }

    /**
     * 获取备用量数据
     *
     * @param statistics
     * @return
     */
    private Double getAllowanceDosageCount(Map statistics, List<Map> inOutAmountMapList) {
        errorIfEmpty(statistics, "出入量数据为空");
        String useSign = (String) statistics.get("useSign");
        String parentId = (String) statistics.get("parentId");
        if (StringUtils.isNotEmpty(useSign) && (StringUtils.contains(useSign, IN_OUT_AMOUNT_ALL_ALLOWANCE_DOSAGE) && isExistThisDataList(inOutAmountMapList, parentId)))
            //  if (StringUtils.isNotEmpty(useSign) && StringUtils.contains(useSign, IN_OUT_AMOUNT_ALL_ALLOWANCE_DOSAGE))
            return 0.0;
        return objectToInt(statistics.get("allowance_dosage"));
    }

    /**
     * 判断总结是否需要总结数据
     *
     * @param
     * @return
     */
    private boolean isExistThisDataList(List<Map> inOutAmountMapList, String parentId) {
        if (isEmpty(inOutAmountMapList))
            return false;
        if (isEmpty(parentId))
            return false;
        AtomicBoolean isExist = new AtomicBoolean(false);
        inOutAmountMapList.forEach(map -> {
            if (map.containsKey("id") && isNotEmpty(map.get("id")) && StringUtils.equals((String) map.get("id"), parentId))
                isExist.set(true);
        });
        return isExist.get();
    }

    /**
     * 判断id是否存在parentId
     *
     * @param
     * @return
     */
    private boolean isExistThisParentId(List<Map> inOutAmountMapList, String id) {
        if (isEmpty(inOutAmountMapList))
            return false;
        if (isEmpty(id))
            return false;
        AtomicBoolean isExist = new AtomicBoolean(false);
        inOutAmountMapList.forEach(map -> {
            if (map.containsKey("parentId") && isNotEmpty(map.get("parentId")) && StringUtils.equals((String) map.get("parentId"), id))
                isExist.set(true);
        });
        return isExist.get();
    }


    /**
     * 提取数值
     *
     * @return
     */
    private Map<String, Double> extractNum(Map statistics, CustomContent customContent, List<Map> inOutAmountMapList) {
        //实入量
        double dosageCount = objectToInt(statistics.get("dosage"));
        //备用量
        double allowanceDosageCount = getAllowanceDosageCount(statistics, inOutAmountMapList);
        //原先余量
        //  double surplusCountOld = objectToInt(statistics.get("surplus"));
        //余量
        double surplusCount = getSurplusCount(statistics, inOutAmountMapList);
        //出量(尿)
        double pissCount = objectToInt(statistics.get("piss"));
        //出量(便)
        double facesCount = objectToInt(statistics.get("faces"));
        //引流量
        double drainageCount = objectToInt(statistics.get("drainage"));
        //平衡(总入量-总出量)
        double balanceCount = objectToInt(statistics.get("balance"));
        Map<String, Double> countMap = new HashMap<>();
        countMap.put("dosageCount", dosageCount);
        countMap.put("allowanceDosageCount", allowanceDosageCount);
        countMap.put("pissCount", pissCount);
        countMap.put("facesCount", facesCount);
        countMap.put("drainageCount", drainageCount);
        countMap.put("balanceCount", balanceCount);
        countMap.put("surplusCount", surplusCount);
        //    countMap.put("surplusCountOld", surplusCountOld);
        if (Objects.isNull(customContent)) {
            return countMap;
        }
        if (!objectStrIsNull(customContent.getContentOne()) && isDecimals(customContent.getContentOne())) {
            countMap.put("contentOne", Double.valueOf(customContent.getContentOne()));
        }
        if (!objectStrIsNull(customContent.getContentTwo()) && isDecimals(customContent.getContentTwo())) {
            countMap.put("contentTwo", Double.valueOf(customContent.getContentTwo()));
        }
        if (!objectStrIsNull(customContent.getContentThree()) && isDecimals(customContent.getContentThree())) {
            countMap.put("contentThree", Double.valueOf(customContent.getContentThree()));
        }
        if (!objectStrIsNull(customContent.getContentFour()) && isDecimals(customContent.getContentFour())) {
            countMap.put("contentFour", Double.valueOf(customContent.getContentFour()));
        }
        if (!objectStrIsNull(customContent.getContentFive()) && isDecimals(customContent.getContentFive())) {
            countMap.put("contentFive", Double.valueOf(customContent.getContentFive()));
        }
        if (!objectStrIsNull(customContent.getContentSix()) && isDecimals(customContent.getContentSix())) {
            countMap.put("contentSix", Double.valueOf(customContent.getContentSix()));
        }
        if (!objectStrIsNull(customContent.getContentSeven()) && isDecimals(customContent.getContentSeven())) {
            countMap.put("contentSeven", Double.valueOf(customContent.getContentSeven()));
        }
        if (!objectStrIsNull(customContent.getContentEight()) && isDecimals(customContent.getContentEight())) {
            countMap.put("contentEight", Double.valueOf(customContent.getContentEight()));
        }
        if (!objectStrIsNull(customContent.getContentNine()) && isDecimals(customContent.getContentNine())) {
            countMap.put("contentNine", Double.valueOf(customContent.getContentNine()));
        }
        if (!objectStrIsNull(customContent.getContentTen()) && isDecimals(customContent.getContentTen())) {
            countMap.put("contentTen", Double.valueOf(customContent.getContentTen()));
        }
        return countMap;
    }

    /**
     * 精确小数有一位
     *
     * @param str
     * @return
     */
    private double preciseDouble(Object str) {
        DecimalFormat df = new DecimalFormat("0.0");
        return Double.parseDouble(df.format(str));
    }

    /**
     * object转Int
     *
     * @param object
     * @return
     */
    private Double objectToInt(Object object) {
        if (Objects.isNull(object)) {
            return 0.0;
        }
        if (StringUtils.isEmpty(String.valueOf(object)) || StringUtils.isBlank(String.valueOf(object))) {
            return 0.0;
        }
        if (!isDecimals(String.valueOf(object))) {
            return 0.0;
        }
        return Double.valueOf(String.valueOf(object));
    }

    /**
     * 判断所需参数是否都存在
     *
     * @param map
     */
    private void isMapNull(Map<String, Object> map) {
        if (Objects.isNull(map)) {
            throw new IllegalArgumentException("参数为空");
        }
        if (objectStrIsNull(map.get("hours"))) {
            throw new IllegalArgumentException("查询结束时间为空");
        }
        if (objectStrIsNull(map.get("startTime"))) {
            throw new IllegalArgumentException("查询开始时间为空");
        }
        if (objectStrIsNull(map.get("countingTime"))) {
            throw new IllegalArgumentException("统计时刻为空");
        }
        if (objectStrIsNull(map.get("countingHours"))) {
            throw new IllegalArgumentException("间隔小结为空");
        }
        if (objectStrIsNull(map.get("patientId"))) {
            throw new IllegalArgumentException("患者id为空");
        }
    }

    /**
     * 查询数据
     *
     * @param map
     * @return
     */
    public JSONObject getInOutAmountList(Map<String, Object> map) {
        JSONObject json = new JSONObject();
        json.put("code", HttpCode.FAILURE_CODE.getCode());
        json.put("data", new ArrayList<>());
        json.put("msg", "暂无数据");
        if (map == null || !map.containsKey("patientId") || StringUtils.isEmpty(map.get("patientId").toString())) {
            json.put("code", HttpCode.NO_PATIENT_CODE.getCode());
            json.put("msg", "请选择病人");
            return json;
        }
        if (map != null && map.containsKey("start")) {
            int totalCount = inOutAmountDao.getInOutAmountNum(map);
            map.put("start", ((int) map.get("start") - 1) * (int) map.get("size"));
            json.put("totalCount", totalCount);
        }
        //先查询有哪些自定义字段，放入查询条件中   你看看数据库余量是空的应该
        Map<String, Object> m = new HashMap<>();
        m.put("status", 1);
        m.put("associatedTable", "table_in_out_amount");//关联表名
        List<CustomField> list = customFieldDao.queryList(m);
        if (list != null && list.size() > 0) {
            map.put("list", list);
        }
        List<Map<String, Object>> amountList = inOutAmountDao.queryInOutAmountList(map);
        Date nowTime = new Date();
        if (amountList != null && amountList.size() > 0) {
            for (int i = 0; i < amountList.size(); i++) {
                Map<String, Object> amount = amountList.get(i);
                if (StringUtils.isNotEmpty((String) amount.get("flag"))) {
                    continue;
                }
                if (!StringUtils.isEmpty(amount.get("rate").toString())) {//速率不为空说明是泵入
                    if (StringUtils.isEmpty(amount.get("start_time").toString())) {
                        continue;
                    }
                    long min = getMin(amount, nowTime);
                    double dosage = Double.valueOf(amount.get("rate").toString()) * min;
                    if (dosage > Double.valueOf(amount.get("allowance_dosage").toString())) {
                        dosage = Double.valueOf(amount.get("allowance_dosage").toString());
                    }
                    double surplus = 0.0;
                    if (StringUtils.isEmpty(amount.get("surplus").toString())) {//如果余量是空的，自动计算
                        surplus = Double.valueOf((String) amount.get("allowance_dosage")) - dosage;
                    } else {
                        surplus = Double.valueOf((String) amount.get("surplus"));
                    }
                    amount.put("surplus", surplus);
                    amount.put("dosage", dosage);
                    InOutAmount inOutAmount = inOutAmountDao.queryData(amount.get("id").toString());
                    inOutAmount.setDosage(String.valueOf(dosage));
                    inOutAmount.setSurplus(String.valueOf(surplus));
                    inOutAmountDao.update(inOutAmount);

                }
            }
            json.put("msg", "查询成功");
            json.put("data", JSONArray.fromObject(amountList));
        }
        json.put("code", HttpCode.OK_CODE.getCode());
        return json;
    }

    /**
     * 获取时间差（min）
     *
     * @return
     */
    private long getMin(Map<String, Object> amount, Date nowTime) {
        long mins = 0;
        if (!StringUtils.isEmpty(amount.get("end_time").toString())) {
            try {
                long min = Math.abs(nowTime.getTime() - yyyyMMddHHmmSdfToDate(amount.get("end_time").toString()).getTime()) / 60000;
                if (min > 0) {
                    mins = Math.abs(yyyyMMddHHmmSdfToDate(amount.get("end_time").toString()).getTime() - yyyyMMddHHmmSdfToDate(amount.get("start_time").toString()).getTime()) / 60000;
                } else {
                    mins = Math.abs(nowTime.getTime() - yyyyMMddHHmmSdfToDate(amount.get("start_time").toString()).getTime()) / 60000;
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        } else {
            try {
                mins = Math.abs(nowTime.getTime() - yyyyMMddHHmmSdfToDate(amount.get("start_time").toString()).getTime()) / 60000;
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return mins;
    }


    /**
     * 出入量总的统计按天或者小时list
     *
     * @param inOutAmountStatisticRequestDTO
     */
    public HttpResult totalStatistic(InOutAmountStatisticRequestDTO inOutAmountStatisticRequestDTO) {
        try {
            errorIfNull(inOutAmountStatisticRequestDTO);
            errorIfEmpty(inOutAmountStatisticRequestDTO.getStatisticTimeType(), "查询类型不能为空");
            errorIfTrue(!StringUtils.equals(inOutAmountStatisticRequestDTO.getStatisticTimeType(), "day")
                            && !StringUtils.equals(inOutAmountStatisticRequestDTO.getStatisticTimeType(), "hour")
                    , "查询类型无效，只能为天或者小时");
            InOutAmountAllSumDTO inAndOutTotal;
            List<InOutAmountStatisticReturnDTO> list;
            if (isNewForm(inOutAmountStatisticRequestDTO)) {
                inAndOutTotal = nurseRecordFormDao.getInAndOutTotal(inOutAmountStatisticRequestDTO);
                list = nurseRecordFormDao.statisticData(inOutAmountStatisticRequestDTO);
            } else {
                //查询某段时间内总数
                inAndOutTotal = inOutAmountDao.getInAndOutTotal(inOutAmountStatisticRequestDTO);
                list = inOutAmountDao.statisticData(inOutAmountStatisticRequestDTO);
            }
            return new HttpResult(200, setToTalNum(list, inAndOutTotal), "数据查询成功");
        } catch (JyxdException e) {
            return new HttpResult(400, e.getMessage());
        } catch (Exception e) {
            return new HttpResult(500, "内部服务器错误");
        }
    }

    /**
     * 判断是否使用新的表单统计
     *
     * @param inOutAmountStatisticRequestDTO
     * @return
     */
    private boolean isNewForm(InOutAmountStatisticRequestDTO inOutAmountStatisticRequestDTO) {
        if (Objects.isNull(inOutAmountStatisticRequestDTO))
            return false;
        if (StringUtils.isEmpty(inOutAmountStatisticRequestDTO.getNewOrOld()))
            return false;
        if (StringUtils.equals(inOutAmountStatisticRequestDTO.getNewOrOld(), "new"))
            return true;
        return false;
    }

    /**
     * 赋值总数到列表第一条
     *
     * @param list
     * @param inAndOutTotal
     * @return
     */
    private List<InOutAmountStatisticReturnDTO> setToTalNum(List<InOutAmountStatisticReturnDTO> list, InOutAmountAllSumDTO inAndOutTotal) {
        if (CollectionUtils.isEmpty(list)) {
            return list;
        }
        if (Objects.isNull(inAndOutTotal)) {
            return list;
        }
        InOutAmountStatisticReturnDTO inOutAmountStatisticReturnDTO = new InOutAmountStatisticReturnDTO();
        inOutAmountStatisticReturnDTO.setDescribe("总计");
        inOutAmountStatisticReturnDTO.setDosageSum(inAndOutTotal.getDosageTotalSum());
        inOutAmountStatisticReturnDTO.setBalanceSum(inAndOutTotal.getBalanceTotalSum());
        inOutAmountStatisticReturnDTO.setOutSum(inAndOutTotal.getOutTotalSum());
        list.add(0, inOutAmountStatisticReturnDTO);
        return list;
    }

    /**
     * 出入量总的统计
     *
     * @param inOutAmountStatisticRequestDTO
     */
    public HttpResult getInAndOutTotal(InOutAmountStatisticRequestDTO inOutAmountStatisticRequestDTO) {
        try {
            errorIfNull(inOutAmountStatisticRequestDTO);
            InOutAmountAllSumDTO inOutAmountTotal;
            if (isNewForm(inOutAmountStatisticRequestDTO))
                inOutAmountTotal = nurseRecordFormDao.getInAndOutTotal(inOutAmountStatisticRequestDTO);
            else
                inOutAmountTotal = inOutAmountDao.getInAndOutTotal(inOutAmountStatisticRequestDTO);
            return new HttpResult(200, inOutAmountTotal, "数据查询成功");
        } catch (JyxdException e) {
            return new HttpResult(400, e.getMessage());
        } catch (Exception e) {
            return new HttpResult(500, "内部服务器错误");
        }
    }


    /**
     * 验证传参数据合法性
     *
     * @param inOutAmountStatisticRequestDTO
     */
    private void errorIfNull(InOutAmountStatisticRequestDTO inOutAmountStatisticRequestDTO) {
        errorIfEmpty(inOutAmountStatisticRequestDTO, "传输参数不能为空");
        errorIfEmpty(inOutAmountStatisticRequestDTO.getPatientId(), "患者id不能为空");
        errorIfEmpty(inOutAmountStatisticRequestDTO.getStartTime(), "查询开始时间不能为空");
        errorIfEmpty(inOutAmountStatisticRequestDTO.getEndTime(), "查询结束时间不能为空");
    }

    /**
     * 出入量2合一导出
     *
     * @param inOutAmountStatisticRequestDTO
     */
    public void exportExcelTotalStatistic(InOutAmountStatisticRequestDTO inOutAmountStatisticRequestDTO, HttpServletResponse response) throws Exception {
        List<InOutAmountStatisticReturnDTO> downloadList;
        if (isNewForm(inOutAmountStatisticRequestDTO))
            downloadList = nurseRecordFormDao.statisticData(inOutAmountStatisticRequestDTO);
        else
            downloadList = inOutAmountDao.statisticData(inOutAmountStatisticRequestDTO);
        if (downloadList != null && downloadList.size() > 0) {
            ExportExcelUtil.exportExcel(response, "出入量信息统计" + System.currentTimeMillis() + ".xls", setExcelData(downloadList));
        } else {
            response.getWriter().print("暂无数据");
        }
    }

    /**
     * 添加excel导出信息
     *
     * @param list
     * @return
     */
    public static ExcelData setExcelData(List<InOutAmountStatisticReturnDTO> list) {

        ExcelData data = new ExcelData();
        data.setName("出入量信息统计表");
        List<String> titles = new ArrayList();
        titles.add("日期");
        titles.add("入量");
        titles.add("出量");
        titles.add("平衡量");
        data.setTitles(titles);
        if (list != null && list.size() > 0) {

            List<List<Object>> rows = new ArrayList();
            float dosageSum = 0.0f;
            float outSum = 0.0f;
            float balanceSum = 0.0f;
            List<Object> rowSum = new ArrayList();
            //添加总计
            for (InOutAmountStatisticReturnDTO inOutAmountStatisticReturnDTO : list) {
                dosageSum += Float.parseFloat(inOutAmountStatisticReturnDTO.getDosageSum());
                outSum += Float.parseFloat(inOutAmountStatisticReturnDTO.getOutSum());
                balanceSum += Float.parseFloat(inOutAmountStatisticReturnDTO.getBalanceSum());
            }
            rowSum.add("总计");
            rowSum.add(dosageSum);
            rowSum.add(outSum);
            rowSum.add(balanceSum);
            rows.add(rowSum);
            for (InOutAmountStatisticReturnDTO inOutAmountStatisticReturnDTO : list) {
                List<Object> row1 = new ArrayList();
                row1.add(inOutAmountStatisticReturnDTO.getDataTime());
                row1.add(inOutAmountStatisticReturnDTO.getDosageSum());
                row1.add(inOutAmountStatisticReturnDTO.getOutSum());
                row1.add(inOutAmountStatisticReturnDTO.getBalanceSum());
                rows.add(row1);
            }
            data.setRows(rows);
        }
        return data;
    }
}
